import request from "@/libs/request";
import { ConvertNumberToLetter } from "@/libs/tool";

const size = { col: 40, row: 60 };
const pxTomm = 0.2646;
const cellWidth = 2.052; // 单元格的单位宽度(mm)
const cellHeight = 0.3528; // 单元格的单位高度(mm)
const defaultUnitWidth = 14; // 默认单元格宽度
const defaultUnitHeight = 20; // 默认单元格高度

export const entity = {};

export let InitTable = (obj) => {
  if (obj) {
    Object.assign(entity, obj);
  }

  entity.templateId = null;
  entity.templateName = null;
  entity.remark = null;
  entity.router.replace({
    path: "/",
  });

  // 行
  let rows = [
    {
      top: 0,
      width: (7 * cellWidth) / pxTomm,
      height: (20 * cellHeight) / pxTomm,
    },
  ];
  for (let i = 1; i <= size.row; i++) {
    rows.push({
      top: rows[i - 1].top + (rows[i - 1].height + 1),
      width: (7 * cellWidth) / pxTomm,
      height: (defaultUnitHeight * cellHeight) / pxTomm,
      unitHeight: defaultUnitHeight,
      label: i,
    });
  }
  entity.rowIndex.value = rows;

  // 列
  let cols = [
    {
      left: 0,
      width: (7 * cellWidth) / pxTomm,
      height: (20 * cellHeight) / pxTomm,
    },
  ];
  for (let i = 1; i <= size.col; i++) {
    cols.push({
      left: cols[i - 1].left + (cols[i - 1].width + 1),
      width: (defaultUnitWidth * cellWidth) / pxTomm,
      height: (20 * cellHeight) / pxTomm,
      unitWidth: defaultUnitWidth,
      label: ConvertNumberToLetter(i),
    });
  }
  entity.colIndex.value = cols;

  // 单元格
  let cells = [];
  for (let i = 0; i < size.row; i++) {
    cells.push([]);
    for (let j = 0; j < size.col; j++) {
      cells[i].push({
        show: true,
        text: "",
        row: i,
        col: j,
        rowspan: 0,
        colspan: 0,
        top: i == 0 ? 1 : cells[i - 1][j].top + cells[i - 1][j].height + 1,
        left: j == 0 ? 1 : cells[i][j - 1].left + cells[i][j - 1].width + 1,
        width: cols[j + 1].width,
        height: rows[i + 1].height,

        textAlign: "left",
        bold: "normal",
        italic: "normal",
        underline: "none",
        fontSize: 11,
        color: "#000",
        background: "#fff",
      });
    }
  }
  entity.cells.value = cells;
};

export let LoadTable = (obj) => {
  InitTable();

  entity.templateId = obj.templateId ?? null;
  entity.templateName = obj.templateName ?? null;
  entity.remark = obj.remark ?? null;
  if (entity.templateName) {
    entity.router.replace({
      path: "/",
      query: { 表格名称: entity.templateName },
    });
  } else {
    entity.router.replace({
      path: "/",
    });
  }

  let save = JSON.parse(obj.templateConfig);

  // 行
  for (let i = 0; i < save.height.length; i++) {
    entity.rowIndex.value[i + 1].height =
      (save.height[i] * cellHeight) / pxTomm;
    entity.rowIndex.value[i + 1].unitHeight = save.height[i];
  }
  let top = 0;
  for (let i = 1; i < entity.rowIndex.value.length; i++) {
    top += entity.rowIndex.value[i - 1].height + 1;
    entity.rowIndex.value[i].top = top;
  }

  // 列
  for (let i = 0; i < save.width.length; i++) {
    entity.colIndex.value[i + 1].width = (save.width[i] * cellWidth) / pxTomm;
    entity.colIndex.value[i + 1].unitWidth = save.width[i];
  }
  let left = 0;
  for (let i = 1; i < entity.colIndex.value.length; i++) {
    left += entity.colIndex.value[i - 1].width + 1;
    entity.colIndex.value[i].left = left;
  }

  // 单元格
  for (let i = 0; i < save.cells.length; i++) {
    entity.cells.value[save.cells[i].row][save.cells[i].col].text =
      save.cells[i].text;
    if (save.cells[i].rowspan) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].rowspan =
        save.cells[i].rowspan;
    }
    if (save.cells[i].colspan) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].colspan =
        save.cells[i].colspan;
    }

    if (save.cells[i].textAlign) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].textAlign =
        save.cells[i].textAlign;
    }
    if (save.cells[i].bold) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].bold =
        save.cells[i].bold;
    }
    if (save.cells[i].italic) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].italic =
        save.cells[i].italic;
    }
    if (save.cells[i].underline) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].underline =
        save.cells[i].underline;
    }
    if (save.cells[i].fontSize) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].fontSize =
        save.cells[i].fontSize;
    }
    if (save.cells[i].color) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].color =
        save.cells[i].color;
    }
    if (save.cells[i].background) {
      entity.cells.value[save.cells[i].row][save.cells[i].col].background =
        save.cells[i].background;
    }

    for (
      let m = 0;
      m <= entity.cells.value[save.cells[i].row][save.cells[i].col].rowspan;
      m++
    ) {
      for (
        let n = 0;
        n <= entity.cells.value[save.cells[i].row][save.cells[i].col].colspan;
        n++
      ) {
        if (m == 0 && n == 0) {
          continue;
        }
        entity.cells.value[save.cells[i].row + m][
          save.cells[i].col + n
        ].show = false;
      }
    }
  }
  for (let i = 0; i < entity.cells.value.length; i++) {
    for (let j = 0; j < entity.cells.value[i].length; j++) {
      entity.cells.value[i][j].top =
        entity.rowIndex.value[i + 1].top - entity.rowIndex.value[0].height;
      entity.cells.value[i][j].left =
        entity.colIndex.value[j + 1].left - entity.colIndex.value[0].width;

      let width = 0;
      for (let m = 0; m <= entity.cells.value[i][j].colspan; m++) {
        width += entity.colIndex.value[j + m + 1].width;
      }
      entity.cells.value[i][j].width = width;

      let height = 0;
      for (let m = 0; m <= entity.cells.value[i][j].rowspan; m++) {
        height += entity.rowIndex.value[i + m + 1].height;
      }
      entity.cells.value[i][j].height = height;
    }
  }
};

export let selecting = false;
export let startCell = null;
export let lastCell = null;

export let UpdateRangeStart = (obj) => {
  startCell = entity.cells.value[obj.row][obj.col];
  lastCell = null;
  RangeStart();
  selecting = true;
};

export let UpdateRangeMove = (obj) => {
  if (selecting) {
    lastCell = entity.cells.value[obj.row][obj.col];
    RangeMove();
  }
};

let RangeStart = () => {
  Object.assign(entity.range.value, startCell);
  entity.range.value.show = true;
  entity.range.value.top += entity.colIndex.value[0].height;
  entity.range.value.left += entity.rowIndex.value[0].width;
  entity.range.value.width += startCell.colspan;
  entity.range.value.height += startCell.rowspan;
  entity.range.value.more = false;
};

let RangeMove = () => {
  let absWidth = Math.abs(lastCell.left - startCell.left);
  let absHeight = Math.abs(lastCell.top - startCell.top);
  Object.assign(entity.range.value, {
    top: lastCell.top > startCell.top ? startCell.top : lastCell.top,
    left: lastCell.left > startCell.left ? startCell.left : lastCell.left,
    width:
      lastCell.left > startCell.left
        ? absWidth + lastCell.width
        : absWidth + startCell.width,
    height:
      lastCell.top > startCell.top
        ? absHeight + lastCell.height
        : absHeight + startCell.height,
  });
  entity.range.value.top += entity.colIndex.value[0].height;
  entity.range.value.left += entity.rowIndex.value[0].width;
  entity.range.value.width +=
    lastCell.left > startCell.left ? lastCell.colspan : startCell.colspan;
  entity.range.value.height +=
    lastCell.top > startCell.top ? lastCell.rowspan : startCell.rowspan;
  if (lastCell.row == startCell.row && lastCell.col == startCell.col) {
    entity.range.value.more = false;
  } else {
    entity.range.value.more = true;
  }
};

export let UpdateRangeEnd = () => {
  selecting = false;
};

export let UpdateColWidth = (obj) => {
  let offset =
    obj.left -
    entity.colIndex.value[obj.index].left -
    entity.colIndex.value[obj.index].width;

  entity.colIndex.value[obj.index].width += offset;
  entity.colIndex.value[obj.index].unitWidth =
    (entity.colIndex.value[obj.index].width / cellWidth) * pxTomm;

  for (let i = obj.index + 1; i < entity.colIndex.value.length; i++) {
    entity.colIndex.value[i].left += offset;
  }
  for (let i = 0; i < entity.cells.value.length; i++) {
    for (let j = obj.index; j < entity.cells.value[i].length; j++) {
      entity.cells.value[i][j].left += offset;
    }
  }

  UpdateCell();

  if (lastCell) {
    RangeMove(lastCell);
  } else if (startCell) {
    RangeStart(startCell);
  }
};

export let UpdateRowHeight = (obj) => {
  let offset =
    obj.top -
    entity.rowIndex.value[obj.index].top -
    entity.rowIndex.value[obj.index].height;

  entity.rowIndex.value[obj.index].height += offset;
  entity.rowIndex.value[obj.index].unitHeight =
    (entity.rowIndex.value[obj.index].height / cellHeight) * pxTomm;

  for (let i = obj.index + 1; i < entity.rowIndex.value.length; i++) {
    entity.rowIndex.value[i].top += offset;
  }
  for (let i = obj.index - 1; i < entity.cells.value.length; i++) {
    if (i > obj.index - 1) {
      for (let j = 0; j < entity.cells.value[i].length; j++) {
        entity.cells.value[i][j].top += offset;
      }
    }
  }

  UpdateCell();

  if (lastCell) {
    RangeMove(lastCell);
  } else if (startCell) {
    RangeStart(startCell);
  }
};

let UpdateCell = () => {
  for (let i = 0; i < entity.cells.value.length; i++) {
    for (let j = 0; j < entity.cells.value[i].length; j++) {
      let cell = entity.cells.value[i][j];
      let width = 0;
      let height = 0;
      for (let k = cell.row; k <= cell.row + cell.rowspan; k++) {
        height += entity.rowIndex.value[k + 1].height;
      }
      for (let k = cell.col; k <= cell.col + cell.colspan; k++) {
        width += entity.colIndex.value[k + 1].width;
      }
      cell.width = width;
      cell.height = height;
    }
  }
};

export let SaveTable = () => {
  let cells = [];
  let range = { row: -1, col: -1 };
  for (let i = 0; i < entity.cells.value.length; i++) {
    for (let j = 0; j < entity.cells.value[i].length; j++) {
      let cell = entity.cells.value[i][j];
      if (!(cell.show && cell.text && cell.text.length != 0)) {
        continue;
      }

      let tmp = {
        text: cell.text,
        row: cell.row,
        col: cell.col,
      };
      if (cell.rowspan != 0) {
        tmp.rowspan = cell.rowspan;
      }
      if (cell.colspan != 0) {
        tmp.colspan = cell.colspan;
      }

      if (cell.textAlign != "left") {
        tmp.textAlign = cell.textAlign;
      }
      if (cell.bold != "normal") {
        tmp.bold = cell.bold;
      }
      if (cell.italic != "normal") {
        tmp.italic = cell.italic;
      }
      if (cell.underline != "none") {
        tmp.underline = cell.underline;
      }
      if (cell.fontSize != 11) {
        tmp.fontSize = cell.fontSize;
      }
      if (cell.color != "#000") {
        tmp.color = cell.color;
      }
      if (cell.background != "#fff") {
        tmp.background = cell.background;
      }

      cells.push(tmp);

      if (range.row < cell.row) {
        range.row = cell.row + cell.rowspan;
      }
      if (range.col < cell.col) {
        range.col = cell.col + cell.colspan;
      }
    }
  }

  let height = [];
  for (let i = 0; i <= range.row; i++) {
    height.push(entity.rowIndex.value[i + 1].unitHeight);
  }

  let width = [];
  for (let i = 0; i <= range.col; i++) {
    width.push(entity.colIndex.value[i + 1].unitWidth);
  }

  let save = {
    cells,
    range,
    width,
    height,
  };

  let loading = ElLoading.service({
    lock: true,
    text: "Saving...",
    background: "rgba(0, 0, 0, 0.7)",
  });

  if (entity.templateId) {
    request({
      url: import.meta.env.VITE_APP_ENV + "/template",
      method: "put",
      data: {
        templateId: entity.templateId,
        templateConfig: JSON.stringify(save),
      },
    })
      .then(() => {
        ElMessage({
          type: "success",
          message: "保存成功！",
        });
        loading.close();
      })
      .catch(() => {
        loading.close();
      });
  } else {
    request({
      url: import.meta.env.VITE_APP_ENV + "/template",
      method: "post",
      data: {
        templateName: entity.templateName,
        templateConfig: JSON.stringify(save),
        remark: entity.remark,
      },
    })
      .then((res) => {
        entity.templateId = res.data.templateId;
        entity.router.replace({
          path: "/",
          query: { 表格名称: entity.templateName },
        });
        ElMessage({
          type: "success",
          message: "保存成功！",
        });
        loading.close();
      })
      .catch(() => {
        loading.close();
      });
  }
};

export let VirtualTable = (dom) => {
  let range = {
    top: dom.scrollTop,
    left: dom.scrollLeft,
    right: dom.scrollLeft + dom.clientWidth,
    bottom: dom.scrollTop + dom.clientHeight,
  };
  for (let i = 0; i < entity.cells.value.length; i++) {
    for (let j = 0; j < entity.cells.value[i].length; j++) {
      let cell = entity.cells.value[i][j];
      if (
        cell.top + cell.height > range.top ||
        cell.left + cell.width > range.left ||
        cell.top < range.bottom ||
        cell.left < range.right
      ) {
        cell.virtual = false;
      } else {
        cell.virtual = true;
      }
    }
  }
};
